﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace DataWorks_Tools.LSTMDetails
{
    public class CsvNormalizer
    {
        private readonly string csvName;
        private readonly List<Dictionary<string, double>> rawRows;
        /// 所有列的数据，每列对应一个 List<float>，只读
        public readonly List<List<float>> onlyData;
        public readonly List<string> header;
        public readonly bool isFirst;
        public readonly int rowcount;
        /// <summary>
        /// 构造函数：读取 CSV 并初始化只读数据
        /// </summary>
        public CsvNormalizer(FileInfo csvfile)
        {
            csvName = csvfile.Name;
            rawRows = new List<Dictionary<string, double>>();
            onlyData = new List<List<float>>();
            
            using var reader = new StreamReader(csvfile.FullName);
            header = reader.ReadLine()?.Split(',').ToList() ?? throw new Exception("CSV 文件没有 header");

            for (int i = 0; i < header.Count; i++)
                onlyData.Add(new List<float>());

            while (!reader.EndOfStream)
            {
                var line = reader.ReadLine();
                var values = line?.Split(',');

                var rowDict = new Dictionary<string, double>();
                for (int i = 0; i < header.Count && i < values?.Length; i++)
                {
                    if (double.TryParse(values[i], NumberStyles.Any, CultureInfo.InvariantCulture, out double val))
                    {
                        rowDict[header[i]] = val;
                        onlyData[i].Add((float)val); // 按列保存
                    }
                    else
                    {
                        rowDict[header[i]] = 0.0;
                        onlyData[i].Add(0f);
                    }
                }

                rawRows.Add(rowDict);
            }

            var namelist = csvName.Split('-');
            isFirst = namelist.Length > 2 && namelist[2] == "1";
            rowcount=rawRows.Count;
        }

        /// <summary>
        /// 无状态化归一化：返回归一化后的 float[] 列表，每个元素对应 CSV 一行
        /// </summary>
        public List<float[]> GetNormalizedInput(MinMaxScaler scaler)
        {
            var normInputData = new List<float[]>();
            var features = scaler.GetFeatureOrder();

            foreach (var row in rawRows)
            {
                var input = features.ToDictionary(f => f, f => row.ContainsKey(f) ? row[f] : 0.0);
                normInputData.Add(scaler.Normalize(input));
            }

            return normInputData;
        }

        /// <summary>
        /// 获取 normInputData 的最后 N 行
        /// </summary>
        public List<float[]> GetLastNElements(List<float[]> normInputData, int count = 49)
        {
            int start = Math.Max(0, normInputData.Count - count);
            return normInputData.GetRange(start, normInputData.Count - start);
        }

        /// <summary>
        /// 合并两个数据列表
        /// </summary>
        public static List<float[]> MergeFloatArrayLists(List<float[]> first, List<float[]> second, bool order)
        {
            if (!order)
                return first.Concat(second).ToList();
            else
                return second.Concat(first).ToList();
        }

        /// <summary>
        /// 将归一化预测结果反归一化
        /// </summary>
        public List<float> GetDenormalizedValues(List<float> predicted, MinMaxScaler yScaler, string outputFeature)
        {
            var denormList = new List<float>(predicted.Count);
            foreach (var val in predicted)
            {
                denormList.Add((float)yScaler.Denormalize(val, outputFeature));
            }
            return denormList;
        }

        /// <summary>
        /// 返回 CSV 所有原始行（只读）
        /// </summary>
        public List<Dictionary<string, double>> GetRawRows() => rawRows;
    }
}
